package com.woniu.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.woniu.entity.*;
import com.woniu.entity.vo.UserVo;
import com.woniu.service.LogService;
import com.woniu.service.UserService;
import com.woniu.utils.CheckCodeUtil;
import com.woniu.utils.IpUtils;
import com.woniu.utils.ResultObj;
import eu.bitwalker.useragentutils.UserAgent;
import io.minio.*;
import io.minio.http.Method;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api/users")
@CrossOrigin
public class UserController {
    final static String emailcodeN="dasdasdSFAFASFASfasfFDAs56156651522";
    static String checkcode = "";
    static String emailcode = emailcodeN;
    @Autowired
    MinioClient minioClient;
    @Autowired
    LogService logService;
    @Autowired
    private UserService userService;

    @GetMapping("/getTeachers")
    public ResultObj getTeachers(Integer pageNum, Integer pageSize) {
        PageResult teachers = userService.getTeachers(pageNum, pageSize);
        return ResultObj.ok(teachers);
    }

    @PostMapping("/login")
    public SaResult login(@RequestBody UserVo userVo, HttpServletRequest request) {
        if (checkcode.equalsIgnoreCase(userVo.getCheckcode()) && userVo.getCheckcode() != null && !userVo.getCheckcode().equals("")) {
            User u = userService.selectByUserNameAndPassword(userVo.getUsername(), userVo.getPassword());
            if (u != null) {
                //会话登录
                StpUtil.login(u.getUserId(), 30 * 24 * 3600);//30天
                // 与常规登录不同点之处：这里需要把 Token 信息从响应体中返回到前端
                SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
                List<String> roleList = StpUtil.getRoleList(u.getUserId());
                tokenInfo.setTag(roleList.get(0));
                //生成日志
                String ip = IpUtils.getIp(request);
                String address = IpUtils.getCityInfo(ip);
                UserAgent userAgent = IpUtils.getUserAgent(request);
                String browserName = userAgent.getBrowser().getName();
                String operatingSystemName = userAgent.getOperatingSystem().getName();
                Date date = new Date();
                System.out.println(TimeZone.getDefault());
                String action = "登录成功";
                WebLog webLog = new WebLog(ip, address, operatingSystemName, browserName, action, date);
                logService.addLog(webLog);
                return SaResult.data(tokenInfo);
            }
            return SaResult.error("账号或密码错误");
        } else {
            return SaResult.error("验证码错误");
        }
    }

    @PostMapping("/loginout")
    public SaResult loginout() {
        StpUtil.logout();
        return SaResult.ok("账号已退出");
    }

    @PostMapping("/register")
    public ResultObj register(@RequestBody UserVo user,HttpServletRequest request) {
        if (emailcode.equals(user.getCheckcode()) && user.getCheckcode() != null && !user.getCheckcode().equals("")) {
            if (userService.register(user)) {
                emailcode=emailcodeN;
                //生成日志
                String ip = IpUtils.getIp(request);
                String address = IpUtils.getCityInfo(ip);
                UserAgent userAgent = IpUtils.getUserAgent(request);
                String browserName = userAgent.getBrowser().getName();
                String operatingSystemName = userAgent.getOperatingSystem().getName();
                Date date = new Date();
                String action = "注册成功";
                WebLog webLog = new WebLog(ip, address, operatingSystemName, browserName, action, date);
                logService.addLog(webLog);
                return ResultObj.ok().msg("注册成功");
            } else {
                return ResultObj.error().msg("用户名已存在");
            }
        } else {
            return ResultObj.error().msg("验证码错误");
        }
    }

    @PostMapping("savaUserAnswer")
    public ResultObj savaUserAnswer(@RequestBody UserAnswer userAnswer) {
        System.out.println(userAnswer);
        UserAnswer ua = userService.selectByUserIdAndVedioId(userAnswer.getUserId(),userAnswer.getVideoId());
        if (ua!=null){
            userAnswer.setId(ua.getId());
            userService.updateUserAnswer(userAnswer);
        }else {
            userService.addUserAnswer(userAnswer);
        }
        return ResultObj.ok();
    }
    @GetMapping("getUserAnswer")
    public ResultObj getUserAnswer(Integer userId,Integer videoId) {
        System.out.println(userId+"========="+videoId);
        UserAnswer userAnswer = userService.selectByUserIdAndVedioId(userId, videoId);
        System.out.println(userAnswer);
        if(userAnswer != null){
            userAnswer.setTest(JSON.toJSON(userAnswer.getTest()).toString());
            return ResultObj.ok(userAnswer);
        }else {
            return ResultObj.error();
        }
    }
    @GetMapping("getUserAnswerList")
    public ResultObj getUserAnswerList(Integer userId,Integer pageNum, Integer pageSize) {
        PageResult pageResult = userService.selectByUserId(userId, pageNum, pageSize);
        return ResultObj.ok(pageResult);
    }



    @DeleteMapping("deleteUserAnswer")
    public ResultObj deleteUserAnswer(Integer userId,Integer videoId) {
         userService.deleteUserAnswer(userId, videoId);

        return ResultObj.error();

    }



    @PostMapping("checkCode")
    protected SaResult checkCode() {
        // 验证码图片保存路径
        String outputPath = "./checkCode.jpg";
        File file = new File(outputPath);
        int width = 100;    // 图片宽度
        int height = 50;   // 图片高度
        int codeLength = 4; // 验证码长度
        try {
            // 生成验证码并保存到文件
            String verifyCode = CheckCodeUtil.outputVerifyImage(
                    width,
                    height,
                    file,
                    codeLength
            );
            checkcode = verifyCode;
            if (file != null && file.exists()) {
                MultipartFile cMultiFile = new MockMultipartFile("file", file.getName(), null, new FileInputStream(file));
                UploadResult java113 = uploadFile(cMultiFile, "java113");
                String fileUrl = java113.getFileUrl();
                return SaResult.data(fileUrl);
            }
            return SaResult.error("验证码刷新失败");
        } catch (IOException e) {
            e.printStackTrace();
            return SaResult.error("验证码刷新失败");
        }
    }



    // 通用的文件上传方法
    private UploadResult uploadFile(MultipartFile file, String bucketName) {
        String fileName = file.getOriginalFilename();
        long size = file.getSize();
        try {
            InputStream inputStream = file.getInputStream();

            // 检查存储桶是否存在，不存在则创建
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!found) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            // 上传文件
            ObjectWriteResponse oss = minioClient.putObject(
                    PutObjectArgs.builder()
                            .stream(inputStream, size, -1L)
                            .object(fileName)
                            .bucket(bucketName)
                            .build()
            );

            // 获取文件访问URL
            String url = minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .object(fileName)
                            .build());

            return new UploadResult(oss.object(), url);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    @PostMapping("/getUserInfo")
    public SaResult getUserInfo() {
        Object loginId = StpUtil.getLoginId();
        if (loginId != null || StpUtil.isLogin()) {
            User user = userService.getUserById(Integer.parseInt(loginId + ""));
            return SaResult.data(user);
        } else {
            return SaResult.data("未登录");

        }
    }

    @PostMapping("/getEmailCode")
    public ResultObj getEmailCode(@RequestBody User user) {
        String code = achieveCode();
        emailcode = code;
        // 取消之前可能存在的定时任务（避免多次生成验证码时任务堆积）
        cancelPreviousTask();
        try {
            SimpleEmail mail = new SimpleEmail();
            mail.setHostName("smtp.qq.com");//发送邮件的服务器
            mail.setAuthentication("371881780@qq.com", "ygjcnkjxpuzhbgjj");//刚刚记录的授权码，是开启SMTP的密码
            mail.setFrom("371881780@qq.com", "蜗牛ai课程");  //发送邮件的邮箱和发件人
            mail.setSSLOnConnect(true); //使用安全链接
            mail.addTo(user.getEmail());//接收的邮箱
            mail.setSubject("注册验证码");//设置邮件的主题
            mail.setMsg("尊敬的用户:你好!\n 注册验证码为:" + code + "\n" + "     (有效期为一分钟)");//设置邮件的内容
            mail.send();//发送
            // 安排60秒后执行验证码失效任务
            scheduleCodeExpiration();
        } catch (EmailException e) {
            // 发送失败时也需要取消可能存在的任务
            cancelPreviousTask();
            e.printStackTrace();
        }
        return ResultObj.ok();
    }
    // 定时任务服务
    private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
    // 记录当前定时任务，用于取消
    private java.util.concurrent.ScheduledFuture<?> codeExpirationTask;

    // 安排验证码失效任务
    private void scheduleCodeExpiration() {
        codeExpirationTask = scheduler.schedule(() -> {
            // 60秒后将验证码设置为失效状态
            emailcode = emailcodeN;
            System.out.println("验证码已失效，当前值: " + emailcode);
        }, 60, TimeUnit.SECONDS);
    }

    // 取消之前的定时任务
    private void cancelPreviousTask() {
        if (codeExpirationTask != null && !codeExpirationTask.isDone()) {
            codeExpirationTask.cancel(true);
            System.out.println("取消之前的验证码失效任务");
        }
    }


    public String achieveCode() {
        String[] beforeShuffle = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9"};
        List list = Arrays.asList(beforeShuffle);//将数组转换为集合
        Collections.shuffle(list);  //打乱集合顺序
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            sb.append(list.get(i)); //将集合转化为字符串
        }
        return sb.toString().substring(2, 8);  //截取字符串第4到8
    }


    @GetMapping("/getUsers")
    public Map<String, Object> getUsers(
            @RequestParam(value = "username", required = false) String username,
            @RequestParam(value = "gender", required = false) String gender,
            @RequestParam(value = "status", required = false) Integer status,
            @RequestParam("pageNum") Integer pageNum,
            @RequestParam("pageSize") Integer pageSize) {
        User user = new User();
        user.setUsername(username);
        user.setGender(gender);
        user.setStatus(status);
        PageInfo<User> pageInfo = userService.getUsersByPage(user, pageNum, pageSize);

        Map<String, Object> result = new HashMap<>();
        result.put("pageNum", pageInfo.getPageNum());
        result.put("pageSize", pageInfo.getPageSize());
        result.put("total", pageInfo.getTotal());
        result.put("pages", pageInfo.getPages());
        result.put("data", pageInfo.getList());

        return result;
    }

    @PostMapping("/add")
    public Map<String, Object> addUser(@RequestBody User user) {
        Map<String, Object> result = new HashMap<>();
        user.setRoleId(3);
        user.setIsdelete(0);
        int count = userService.addUser(user);
        result.put("success", count > 0);
        return result;
    }

    @PutMapping("/update")
    public Map<String, Object> updateUser(@RequestBody User user) {
        Map<String, Object> result = new HashMap<>();
        int count = userService.updateUser(user);
        result.put("success", count > 0);
        return result;
    }

    @DeleteMapping("/delete/{id}")
    public Map<String, Object> deleteUser(@PathVariable("id") Integer id,HttpServletRequest request) {
        Map<String, Object> result = new HashMap<>();
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        Object loginId = tokenInfo.getLoginId();
        User admin = userService.getUserById(Integer.parseInt(loginId + ""));
        User user = userService.getUserById(id);
        //生成日志
        String ip = IpUtils.getIp(request);
        String address = IpUtils.getCityInfo(ip);
        UserAgent userAgent = IpUtils.getUserAgent(request);
        String browserName = userAgent.getBrowser().getName();
        String operatingSystemName = userAgent.getOperatingSystem().getName();
        Date date = new Date();
        String action ="管理员:"+ admin.getUsername()+ "\t删除了\t用户:"+user.getUsername();
        WebLog webLog = new WebLog(ip, address, operatingSystemName, browserName, action, date);
        logService.addLog(webLog);
        int count = userService.deleteUser(id);
        result.put("success", count > 0);
        return result;
    }

    @GetMapping("/detail/{id}")
    public Map<String, Object> getUserDetail(@PathVariable("id") Integer id) {
        Map<String, Object> result = new HashMap<>();
        User user = userService.getUserById(id);
        result.put("data", user);
        result.put("success", user != null);
        return result;
    }

    //修改用户状态
    @PutMapping("/updateStatus")
    public Map<String, Object> updateUserStatus(@RequestBody User user) {
        Map<String, Object> result = new HashMap<>();
        int count = userService.updateUserStatus(user);
        result.put("success", count > 0);
        return result;
    }

    //查询所有教师列表
    @GetMapping("/teachers")
    public ResultObj getTeachers() {
        List<User> teachers = userService.getTeachers();
        return ResultObj.ok(teachers);
    }
    //用户添加收藏
    @GetMapping("/addCollect/{courseId}")
    public ResultObj addCollect(@PathVariable("courseId") Integer courseId){
        Integer uid = Integer.valueOf(StpUtil.getLoginId().toString());
        userService.addCollect(uid,courseId);
        return ResultObj.ok();
    }
    //用户取消收藏
    @GetMapping("/delCollect/{courseId}")
    public ResultObj delCollect(@PathVariable("courseId") Integer courseId){
        Integer uid = Integer.valueOf(StpUtil.getLoginId().toString());
        userService.delCollect(uid,courseId);
        return ResultObj.ok();
    }
}

